package com.blockmeta.bbs.businesslibrary.widget;

import android.content.Context;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import androidx.core.view.NestedScrollingChild;
import androidx.core.view.NestedScrollingChildHelper;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.ViewConfiguration;

import com.blankj.utilcode.util.AppUtils;
import com.blankj.utilcode.util.LogUtils;
import com.blockmeta.bbs.baselibrary.base.app.BaseApp;
import com.tencent.smtt.export.external.extension.interfaces.IX5WebViewExtension;
import com.tencent.smtt.sdk.WebBackForwardList;
import com.tencent.smtt.sdk.WebSettings;
import com.tencent.smtt.sdk.WebView;

import java.lang.reflect.Method;
import java.net.URLEncoder;

public class NestWebView extends WebView implements NestedScrollingChild {

    public interface OnScrollChangedListener
    {
        void onScrollChanged(int left, int top, int oldLeft, int oldTop);
    }

    private OnScrollChangedListener m_Listener;

    public NestWebView(Context context)
    {
        super(context);

        init(context);
    }

    public NestWebView(Context context, AttributeSet attrs)
    {
        super(context, attrs);

        init(context);
    }

    public NestWebView(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);

        init(context);
    }

    public void setOnScrollListener(OnScrollChangedListener listener)
    {
        m_Listener = listener;
    }

    private void init(Context context)
    {
        initSettings(context);
//        setWebChromeClient(new NestWebChromeClient());

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
        {
            setWebContentsDebuggingEnabled(true);
        }

        mChildHelper = new NestedScrollingChildHelper(this);
//        setNestedScrollingEnabled(true);

        mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();
    }

    private void initSettings(Context context)
    {
        WebSettings settings = this.getSettings();
        settings.setJavaScriptEnabled(true);
//        settings.setCacheMode(WebSettings.LOAD_NO_CACHE);
        settings.setLoadWithOverviewMode(true);
        settings.setUseWideViewPort(true);
        settings.setDomStorageEnabled(true);
        settings.setJavaScriptCanOpenWindowsAutomatically(true);
        //缩放操作
        settings.setSupportZoom(true); //支持缩放，默认为true。是下面那个的前提。
        settings.setBuiltInZoomControls(true); //设置内置的缩放控件。若为false，则该WebView不可缩放
        settings.setDisplayZoomControls(false); //隐藏原生的缩放控件
        String userAgentString = settings.getUserAgentString();
        settings.setUserAgent(userAgentString + "/"+ BaseApp.getApplicationId()+"/"
                + AppUtils.getAppVersionName() + "(" + AppUtils.getAppVersionCode() + ")");
//        if (Build.VERSION.SDK_INT >= 21) {
//            // WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
//            settings.setMixedContentMode( 0 );
//        }

        IX5WebViewExtension x5WebViewExtension = getX5WebViewExtension();
        if(x5WebViewExtension != null) {
            x5WebViewExtension.setScrollBarFadingEnabled(false);
        }
        setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
//        removeJavascriptInterfaces(this);
    }

    public static void removeJavascriptInterfaces(WebView webView)
    {
        try {
            Method method = webView.getClass().getMethod(
                    "removeJavascriptInterface", new Class[] { String.class });
            method.invoke(webView, "searchBoxJavaBridge_");
            method.invoke(webView, "accessibility");
            method.invoke(webView, "accessibilityTraversal");
        }
        catch (Exception e)
        {
        }
    }

    public void callJavaScript(String call, String param)
    {
        callJavaScript(this, null, call, param);
    }

    public void callJavaScript(String url, String call, String param)
    {
        callJavaScript(this, url, call, param);
    }

    public static void callJavaScript(WebView webView, String url, String call, String param)
    {
        if (webView == null)
        {
            return;
        }
        if (! TextUtils.isEmpty(url))
        {
            try
            {
                Uri uri = Uri.parse(url);
                String cb = uri.getQueryParameter("cb");

                if (! TextUtils.isEmpty(cb))
                {
                    call = cb;
                }
            }
            catch (Exception e)
            {
            }
        }

        StringBuffer buffer = new StringBuffer();

        buffer.append("javascript:");

        buffer.append(call).append("(");
        if (param == null)
        {
            buffer.append(")");
        }
        else
        {
            buffer.append("'").append(URLEncoder.encode(param)).append("')");
        }

        LogUtils.i("lianzuo", buffer.toString());

        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT)
        {
            webView.evaluateJavascript(buffer.toString(), null);
        }
        else
        {
            webView.loadUrl(buffer.toString());
        }
    }

    @Override
    public WebBackForwardList saveState(Bundle outState)
    {
        WebBackForwardList tWebBackForwardList = super.saveState(outState);
        return tWebBackForwardList;
    }

    @Override
    public WebBackForwardList restoreState(Bundle inState)
    {
        WebBackForwardList tWebBackForwardList = super.restoreState(inState);
        return tWebBackForwardList;
    }

    @Override
    protected void onScrollChanged(int left, int top, int oldleft, int oldtop)
    {
//        LogUtils.i("lianzuo","onScrollChanged l" + left + " t" + top + " oldl" + oldleft + "oldt" + oldtop);
        super.onScrollChanged(left, top, oldleft, oldtop);

        if (m_Listener != null)
        {
            m_Listener.onScrollChanged(left, top, oldleft, oldtop);
        }
    }

    private int mLastY;
    private final int[] mScrollOffset = new int[2];
    private final int[] mScrollConsumed = new int[2];
    private int mNestedOffsetY;
    private NestedScrollingChildHelper mChildHelper;

    private boolean mIsBeingDragged;
    private int mTouchSlop;

//    @Override
//    public boolean dispatchTouchEvent(MotionEvent ev) {
//        boolean returnValue = false;
//
//        MotionEvent event = MotionEvent.obtain(ev);
//        final int action = MotionEventCompat.getActionMasked(event);
//
//        if (action == MotionEvent.ACTION_DOWN) {
//            mNestedOffsetY = 0;
//        }
//        int eventY = (int) event.getY();
//        event.offsetLocation(0, mNestedOffsetY);
//        switch (action) {
//            case MotionEvent.ACTION_MOVE:
//                int deltaY = mLastY - eventY;
//                LogUtils.i("lianzuo", "deltaY:" + deltaY);
//                // NestedPreScroll
//                if (dispatchNestedPreScroll(0, deltaY, mScrollConsumed, mScrollOffset)) {
//                    deltaY -= mScrollConsumed[1];
//                    mLastY = eventY - mScrollOffset[1];
//                    event.offsetLocation(0, -mScrollOffset[1]);
//                    mNestedOffsetY += mScrollOffset[1];
//                    LogUtils.i("lianzuo", "deltaY:" + deltaY + " mlastY" + mLastY + " mScrollConsumed" + mScrollConsumed[1]);
//                }
//
//                if (mScrollConsumed[1] == 0)
//                {
//                    returnValue = super.dispatchTouchEvent(event);
//                }
//                else
//                {
//                    event.setAction(MotionEvent.ACTION_DOWN);
//                    super.dispatchTouchEvent(event);
//                    returnValue = true;
//                }
//
//                // NestedScroll
//                if (dispatchNestedScroll(0, mScrollOffset[1], 0, deltaY, mScrollOffset)) {
//                    event.offsetLocation(0, mScrollOffset[1]);
//                    mNestedOffsetY += mScrollOffset[1];
//                    mLastY -= mScrollOffset[1];
//                    LogUtils.i("lianzuo", "after nestscroll mNestedOffsetY:" + mNestedOffsetY + " mlastY" + mLastY);
//                }
//                break;
//            case MotionEvent.ACTION_DOWN:
//                returnValue = super.dispatchTouchEvent(event);
//
//                mLastY = eventY;
//                // start NestedScroll
//                startNestedScroll(ViewCompat.SCROLL_AXIS_VERTICAL);
//                break;
//            case MotionEvent.ACTION_UP:
//            case MotionEvent.ACTION_CANCEL:
//                returnValue = super.dispatchTouchEvent(event);
//                // end NestedScroll
//                stopNestedScroll();
//                break;
//        }
//        LogUtils.i("lianzuo", "returnValue:" + returnValue);
//        return returnValue;
//    }

    // Nested Scroll implements
    @Override
    public void setNestedScrollingEnabled(boolean enabled) {
        mChildHelper.setNestedScrollingEnabled(enabled);
    }

    @Override
    public boolean isNestedScrollingEnabled() {
        return mChildHelper.isNestedScrollingEnabled();
    }

    @Override
    public boolean startNestedScroll(int axes) {
        return mChildHelper.startNestedScroll(axes);
    }

    @Override
    public void stopNestedScroll() {
        mChildHelper.stopNestedScroll();
    }

    @Override
    public boolean hasNestedScrollingParent() {
        return mChildHelper.hasNestedScrollingParent();
    }

    @Override
    public boolean dispatchNestedScroll(int dxConsumed, int dyConsumed, int dxUnconsumed, int dyUnconsumed,
                                        int[] offsetInWindow) {
        return mChildHelper.dispatchNestedScroll(dxConsumed, dyConsumed, dxUnconsumed, dyUnconsumed, offsetInWindow);
    }

    @Override
    public boolean dispatchNestedPreScroll(int dx, int dy, int[] consumed, int[] offsetInWindow) {
        return mChildHelper.dispatchNestedPreScroll(dx, dy, consumed, offsetInWindow);
    }

    @Override
    public boolean dispatchNestedFling(float velocityX, float velocityY, boolean consumed) {
        return mChildHelper.dispatchNestedFling(velocityX, velocityY, consumed);
    }

    @Override
    public boolean dispatchNestedPreFling(float velocityX, float velocityY) {
        return mChildHelper.dispatchNestedPreFling(velocityX, velocityY);
    }
}
